<script setup name="FileStore">
import { getIcon } from '@/utils/file'
const emits = defineEmits(['layoutChange','typeChange', 'selected','openFolder','update:modelValue'])
const props = defineProps({
  dataSource: {
    type: Array,
    required: true
  },
  keyField: {
    type: String,
    required: true
  },
  layout: {
    type: String,
    default: 'grid'
  },
  type: {
    type: String,
    default: '',
  },
  multiple: {
    type: Boolean,
    default: false
  },
  modelValue: {
    type: [Object , Array],
    default: () => { }
  }
})

const fileType = ref(props.type)

const handleTypeChange = (val) => {
  emits('typeChange', val)
}

const fileLayout = ref(props.layout);
const handleLayout = () => {
  fileLayout.value = fileLayout.value === 'grid' ? 'list' : 'grid';
  emits('layoutChange', fileLayout.value)
}

const pickVal = ref(props.multiple ? props.modelValue : props.modelValue ? [props.modelValue]:[]);

const handleClick = (item) => {
  const { type } = item;
  if(type === 'folder'){
    pickVal.value = [];
    emits('openFolder', item);
    emits('selected', false, null)
    emits('update:modelValue', null)
    return
  }
  if(!props.multiple) {
    //单选
    pickVal.value = [item]
    emits('selected', true, item)
    emits('update:modelValue', item)
  }else{
    //多选，需要判断是否存在，如果存在，则要移除，否则添加
    if(pickVal.value.includes(val)){
      pickVal.value.splice(pickVal.value.indexOf(val), 1)
    }else{
      pickVal.value.push(val)
    }
    emits('selected', true, item)
    emits('update:modelValue', pickVal.value)
  }
}

watch(()=> props.modelValue, (newVal, oldVal) => {
  pickVal.value = props.multiple ? newVal : (newVal ? [newVal]:[]);
})

</script>

<template>
  <div class="file-store-wrapper">
    <div class="file-store-header">
      <div class="file-path">
        /文章图片/20230810
      </div>
      <a-radio-group type="button" size="small" v-model="fileType" class="mx-2" @change="handleTypeChange">
        <a-radio value="">全部</a-radio>
        <a-radio value="picture">图片</a-radio>
        <a-radio value="video">视频</a-radio>
        <a-radio value="audio">音频</a-radio>
        <a-radio value="document">文档</a-radio>
        <a-radio value="other">其他</a-radio>
      </a-radio-group>
      <a-button size="small" @click="handleLayout">
        <template #icon>
          <icon :icon="fileLayout === 'grid' ? 'mingcute:layout-4-line' : 'basil:layout-outline'" />
        </template>
      </a-button>
    </div>
    <div :class="['file-store-content', fileLayout]">
      <template v-if="fileLayout === 'grid'">
        <div :class="['file-item',pickVal && pickVal.map(o=> o[props.keyField]).includes(fileItem[props.keyField]) ? 'active': null]" v-for="fileItem in props.dataSource" @click="handleClick(fileItem)">
          <icon v-if="fileItem.type == 'folder'" icon="material-symbols:folder" color="#ffd664" :size="60" />
          <img :src="fileItem.url" v-else-if="fileItem.type == 'picture'" style="width: 60px;height: 60px" />
          <img :src="fileItem.poster" v-else-if="fileItem.type == 'video'" style="width: 60px;height: 60px" />
          <icon v-else-if="['audio', 'document'].includes(fileItem.type)" :icon="getIcon(fileItem.url)" :size="60" />
          <icon v-else icon="ic:outline-insert-drive-file" :size="50" />
          <span class="file-name">{{ fileItem.name }}</span>
        </div>
      </template>
      <template v-else>
        <div :class="['file-item', i > 0 ? '12mt-2' : null, pickVal && pickVal.map(o => o[props.keyField]).includes(fileItem[props.keyField]) ? 'active': null]" v-for="(fileItem, i) in props.dataSource"
          @click="handleClick(fileItem)">
          <div class="flex">
            <icon v-if="fileItem.type == 'folder'" icon="material-symbols:folder" color="ffd664" :size="20" />
            <img :src="fileItem.url" v-else-if="fileItem.type == 'picture'" style="width: 20px;height: 20px" />
            <img :src="fileItem.url" v-else-if="fileItem.type == 'video'" style="width: 20px;height: 20px" />
            <icon v-else-if="['audio', 'document'].includes(fileItem.type)" :icon="getIcon(fileItem.url)" :size="20" />
            <icon v-else icon="ic:outline-insert-drive-file" :size="50" />
            <span class="file-name">{{ fileItem.name }}</span>
          </div>
          <div>
            <span class="mr-10 text-gray-500">2023-05-15 15:51</span>
            <span class="text-gray-500">128kb</span>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<style lang="less" scoped>
.file-store-wrapper {
  .file-store-header {
    display: flex;
    flex-direction: row;
    justify-content: center;

    .file-path {
      border: 1px solid #e0e0e0;
      flex: 1;
      display: flex;
      align-items: center;
      padding: 0 4px;
      color: var(--color-neutral-6);
    }
  }

  .file-store-content {
    
    margin-top: 10px;

    .file-item {
      width: 80px;
      display: flex;
      cursor: pointer;

      &:hover {
        background-color: var(--color-neutral-2);
      }

      &.active {
        background-color: var(--color-neutral-3);
      }
    }

    &.grid {
      display: grid;
      grid-column-gap: 12px;
      grid-row-gap: 12px;
      grid-template-columns: repeat(auto-fill, 80px);
      grid-template-rows: repeat(auto-fill, 82px);
      .file-item {
        flex-direction: column;
        justify-content: center;
        align-items: center;

        .file-name {
          width: 80px;
          text-align: center;
          overflow: hidden;
          text-overflow: ellipsis;
          word-break: break-all;
          white-space: nowrap;
        }
      }

    }

    &.list {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      .file-item {
        width: 100%;
        padding: 4px;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;

        .file-name {
          margin-left: 4px;
        }

        &:not(:first-child){
          margin-top: 6px;
        }
      }
      
    }
  }
}</style>